package main

import (
	"fmt"
	"log"
	"net/http"
)

const Html = `
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>15.11-Robust_Webserver</title>
</head>
<body>
    <h2>Welcome To Golang</h2>
	%s
</body>
</html>
`

const form = `
<form action="#" method="post" name="var">
	<input type="text" name="in">
	<input type="submit" value="提交">
</form>
`

type actFunc func(http.ResponseWriter, *http.Request)

func logPanic(act actFunc) actFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				log.Printf("[%v] caught panic: %v", r.RemoteAddr, err)
			}
		}()
		act(w, r)
	}
}

func httpHandleFunc(route string, handler actFunc) {
	http.HandleFunc(route, logPanic(handler))
}

func actionIndex(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, Html, "<p>Hello Word, Hello Golang.</p>")
}

func actionForm(w http.ResponseWriter, r *http.Request) {
	var htmlForm = form
	if r.Method == "POST" {
		htmlForm += fmt.Sprintf("<h3>What the input is</h3><p>%s</p>", r.FormValue("in"))
	}
	fmt.Fprintf(w, Html, htmlForm)
}

func main() {
	// http.HandleFunc("/", logPanic(actionIndex))
	// http.HandleFunc("/form", logPanic(actionForm))
	httpHandleFunc("/", actionIndex)
	httpHandleFunc("/form", actionForm)
	if err := http.ListenAndServe(":9999", nil); err != nil {
		panic(err)
	}
}
